package com.zlyx.easy.drools.executor;

import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zlyx.easy.core.utils.FileUtils;
import com.zlyx.easy.core.utils.StringUtils;
import com.zlyx.easy.drools.builder.RuleBuilder;
import com.zlyx.easy.drools.util.DroolsUtils;

/**
 * 规则导入执行器
 * 
 * @ClassName ImportExecutor
 * @Author 赵光
 * @Description ImportExecutor
 * @Date 2020/5/28 0028
 * @Version 1.0
 */
public abstract class ReadExecutor<T> {

	protected Logger log = LoggerFactory.getLogger(getClass());

	protected static final String CLASS_TEMPLATE = "rule/rule.vm";

	/**
	 * 
	 * 渲染类模板
	 * 
	 * @param classBody
	 * @param methodBody
	 * @return
	 * @throws Exception
	 */
	public String renderTemplate(RuleBuilder.RuleBody ruleBody, String ruleName, Map<String, String> props)
			throws Exception {
		ruleBody = doFilter(ruleBody);
		ruleBody.importClass(getTClass());
		props.put("method_body", StringUtils.replaceAll(props.get("method_body"), ruleBody.props()));
		props.put("import_package", ruleBody.header());
		props.put("rule_context_domain", getTClass().getSimpleName());
		String classTemplate = DroolsUtils.render(FileUtils.readResource(CLASS_TEMPLATE), ruleName, props);
		System.out.print("\n=============================================================================\n");
		System.out.print("\n\n输出渲染后文本内容：\n\n");
		System.out.print(classTemplate);
		System.out.print("\n=============================================================================\n");
		return classTemplate;
	}

	/**
	 *
	 * 自定义设置
	 *
	 * @param classBody
	 * @return
	 */
	public RuleBuilder.RuleBody doFilter(RuleBuilder.RuleBody ruleBody) {
		ruleBody.importClass(getTClass()); // 导入类
		ruleBody.placeholders(new HashMap<>()); // 将常量替换为$符号引用的变量(规则导出为java的时候会用到)
		ruleBody.props(new HashMap<>()); // 将$符号引用的替换为变量常量(验证规则的时候会用到)
		return ruleBody;
	}

	/**
	 * 读取抽象类
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Class<T> getTClass() {
		return (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}
}